package com.yanfan.protocol.serialPort.serialPort;

import com.fazecast.jSerialComm.SerialPort;
import com.yanfan.protocol.serialPort.SerialPortOpen;
import com.yanfan.protocol.serialPort.config.SerialPortProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 蚂蚁舞
 */
@Component
public class SerialPortManager {

    private static final Logger logger = LoggerFactory.getLogger(SerialPortManager.class);

    public static final int SERIAL_BAUD_RATE = 115200;

    public static volatile boolean SERIAL_PORT_STATE = false;

    public static volatile SerialPort SERIAL_PORT_OBJECT = null;
    public static volatile SerialPort IS_OPEN = null;

    /**波特率*/
   /* @Value("${serialPort.baudRate}")
    private  Integer  baudRate;*/

    //查找所有可用端口
    public static List<String> getSerialPortList() {
        // 获得当前所有可用串口
        SerialPort[] serialPorts = SerialPort.getCommPorts();
        List<String> portNameList = new ArrayList<String>();
        // 将可用串口名添加到List并返回该List
        for (SerialPort serialPort : serialPorts) {
            //System.out.println(serialPort.getSystemPortName());
            portNameList.add(serialPort.getSystemPortName());
        }
        //去重
        portNameList = portNameList.stream().distinct().collect(Collectors.toList());
        return portNameList;
    }

    //  连接串口
    public static void connectSerialPort(String portName) {
        List<String> serialPortList = SerialPortManager.getSerialPortList();
        if (serialPortList.size() > 0) {
            serialPortList.stream().forEach(port -> {
                if (port.equals(portName)) {      //判断端口是否存在
                    SerialPortOpen.isExit = true;
                    SerialPort serialPort = SerialPortManager.openSerialPort(portName, SerialPortProperties.getStaticBaudRate());
                    try {
                        TimeUnit.MILLISECONDS.sleep(2000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    //给当前串口对象设置监听器
                    serialPort.addDataListener(new SerialPortListener(new SerialPortCallback()));
                    IS_OPEN = serialPort;
                    if (serialPort.isOpen()) {
                        SERIAL_PORT_OBJECT = serialPort;
                        SERIAL_PORT_STATE = true;
                        logger.info(portName + "-- 打开成功!!!!");
                        //System.out.println(portName + "-- 打开成功!!!!");
                    } else {
                        logger.info("端口被占用，打开" + portName + "失败！");
                        //System.out.println("端口被占用，打开" + portName + "失败！");
                    }
        /*else {
            System.out.println(portName + "串口重连中......");
            SerialPortManager.connectSerialPort(portName);
        }*/
                }
            });
            if (!SerialPortOpen.isExit) {
                logger.info("没有可用的" + portName + "，连接串口失败！");
                //System.out.println("没有可用的" + portName + "，连接串口失败！");
            }
        }

    }


    //  打开串口
    public static SerialPort openSerialPort(String portName, Integer baudRate) {
        SerialPort serialPort = SerialPort.getCommPort(portName);
        if (baudRate != null) {
            serialPort.setBaudRate(baudRate);
        }
        if (!serialPort.isOpen()) {  //开启串口
            serialPort.openPort(1000);
        } else {
            return serialPort;
        }
        serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);
        //波特率、数据位、停止位、校验位
        serialPort.setComPortParameters(baudRate, SerialPortProperties.getStaticDataBits(), SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
        serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING, 1000, 1000);
        return serialPort;
    }

    //  关闭串口
    public static void closeSerialPort() {
        if (SERIAL_PORT_OBJECT != null && SERIAL_PORT_OBJECT.isOpen()) {
            SERIAL_PORT_OBJECT.closePort();
            SERIAL_PORT_STATE = false;
            SERIAL_PORT_OBJECT = null;
        }
    }

    //  发送字节数组
    public static void sendSerialPortData(byte[] content) {
        if (SERIAL_PORT_OBJECT != null && SERIAL_PORT_OBJECT.isOpen()) {
            SERIAL_PORT_OBJECT.writeBytes(content, content.length);
        }
    }

    //  读取字节数组
    public static byte[] readSerialPortData() {
        if (SERIAL_PORT_OBJECT != null && SERIAL_PORT_OBJECT.isOpen()) {
            byte[] reslutData = null;
            try {
                if (!SERIAL_PORT_OBJECT.isOpen()) {
                    return null;
                }
                ;
                int i = 0;
                while (SERIAL_PORT_OBJECT.bytesAvailable() > 0 && i++ < 5) Thread.sleep(20);
                byte[] readBuffer = new byte[SERIAL_PORT_OBJECT.bytesAvailable()];
                int numRead = SERIAL_PORT_OBJECT.readBytes(readBuffer, readBuffer.length);
                if (numRead > 0) {
                    reslutData = readBuffer;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return reslutData;
        }
        return null;
    }



}

